package com.mt.repair.service.repairManagement.impl;

import com.mt.common.core.web.JsonResult;
import com.mt.common.system.entity.User;
import com.mt.repair.dao.repairManagement.NoticeCatUserDao;
import com.mt.repair.dao.repairManagement.NoticeDao;

import com.mt.common.core.exception.BusinessException;
import com.mt.common.core.web.base.PageDTO;
import com.mt.common.core.web.base.PageResultDTO;
import com.mt.common.core.web.base.BaseEntity;
import com.mt.common.core.web.BaseService;
import com.mt.repair.service.repairManagement.NoticeCatUserService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.mt.repair.entity.repairManagement.Notice;
import com.mt.repair.service.repairManagement.NoticeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
@Transactional
public class NoticeServiceBean extends BaseService implements NoticeService {

    private static Logger logger = LogManager.getLogger();

	@Autowired
	private NoticeDao noticeDao;

	@Resource
	private RedisTemplate<String, List<Notice>> redisTemplate;

	@Autowired
	StringRedisTemplate stringRedisTemplate;

	@Autowired
	private NoticeCatUserService noticeCatUserService;

	@Autowired
	private NoticeCatUserDao noticeCatUserDao;
	/**
	 * 根据分页参数查询维修评价集合
	 *
	 * @param pageDTO 分页条件
	 */
	@Override
	public PageResultDTO findNotices(PageDTO pageDTO){
        pageDTO.setStartIndex((pageDTO.getCurrentPage()-1)*pageDTO.getPageSize());
		//TODO:请在此校验参数的合法性
		this.validateFindNotices(pageDTO);
		List<Notice> noticeDTOS = this.noticeDao.findNotices(pageDTO);
		Long totalCount = this.noticeDao.findNoticeTotalCount(pageDTO);

		PageResultDTO pageResultDTO = new PageResultDTO();
		pageResultDTO.setTotalCount(totalCount);
		pageResultDTO.setDatas(noticeDTOS);

		return pageResultDTO;
	}

	@Override
	public PageResultDTO findNoticesNotContent(PageDTO pageDTO) {
		pageDTO.setStartIndex((pageDTO.getCurrentPage()-1)*pageDTO.getPageSize());
		//TODO:请在此校验参数的合法性
		this.validateFindNotices(pageDTO);
		List<Notice> noticeDTOS = this.noticeDao.findNoticesNotContent(pageDTO);
		Long totalCount = this.noticeDao.findNoticesNotContentCount(pageDTO);

		PageResultDTO pageResultDTO = new PageResultDTO();
		pageResultDTO.setTotalCount(totalCount);
		pageResultDTO.setDatas(noticeDTOS);

		return pageResultDTO;
	}

	@Override
	public void readNotice(Long noticeId, Long userId) {
		this.noticeCatUserDao.readNotice(noticeId,userId);
	}

	/**
	 * 查询全部维修评价集合
	 *
	 */
	@Override
	public List<Notice> findAllNotices(){
		return this.noticeDao.findAllNotices();
	}

	/**
	 * 查询所有维修评价集合(只提取ID 和 Name)
	 *
	 */
	@Override
	public List<Notice> findAllNoticesWithIdName(){
		//TODO:请在此校验参数的合法性
		this.validateFindAllNoticesWithIdName();
		return this.noticeDao.findAllNoticesWithIdName();
	}

	/**
	 * 根据名称查询维修评价集合(只提取ID 和 Name)
	 *
	 * @param noticeName 名称
	 */
	@Override
	public List<Notice> findNoticesWithIdNameByName(String noticeName){
		//TODO:请在此校验参数的合法性
		this.validateFindNoticesWithIdNameByName(noticeName);
		//TODO:缓存取对应参数
		Set<String> keys = stringRedisTemplate.keys("searchData:Notice_where_noticeName_" + noticeName);
		List<Notice> notices = new ArrayList<>();
		if (keys.isEmpty()) {
		notices = this.noticeDao.findNoticesWithIdNameByName(noticeName);
		redisTemplate.opsForValue().set("searchData:Notice_where_noticeName_" + noticeName, notices, 30, TimeUnit.DAYS);
		} else {
		notices = redisTemplate.opsForValue().get("searchData:Notice_where_noticeName_" + noticeName);
		}
		return notices;
	}

	/**
	 * 根据ID查询指定的维修评价(只提取ID 和 Name)
	 *
	 * @param noticeId Id
	 */
	@Override
	public Notice findNoticesWithIdNameById(Long noticeId){
		//TODO:请在此校验参数的合法性
		this.validateFindNoticesWithIdNameById(noticeId);
		return this.noticeDao.findNoticesWithIdNameById(noticeId);
	}

	/**
	 * 根据ID查询指定的维修评价
	 *
	 * @param noticeId Id
	 */
	@Override
	public Notice findNotice(Long noticeId){
		//TODO:请在此校验参数的合法性
		this.validateFindNotice(noticeId);
		return this.noticeDao.findNotice(noticeId);
	}

	/**
	 * 根据ID查询指定的维修评价(包含外键)
	 *
	 * @param noticeId Id
	 */
	@Override
	public Notice findNoticeWithForeignName(Long noticeId){
		//TODO:请在此校验参数的合法性
		this.validateFindNoticeWithForeignName(noticeId);
		return this.noticeDao.findNoticeWithForeignName(noticeId);
	}

	/**
	 * 新增维修评价
	 *
	 * @param notice 实体对象
	 */
	@Override
	public Notice saveNotice(Notice notice){
		//TODO:请在此校验参数的合法性
		this.validateSaveNotice(notice);
		//TODO:填充公共参数
		this.setSavePulicColumns(notice);
		Long rows = this.noticeDao.saveNotice(notice);
		//发布消息
		if(notice.getPulish().equals(0)){
			this.noticeCatUserService.generate(notice.getEid(),notice.getNoticeType(), notice.getSelectedString());
		}
		if(rows != 1)
		{
			String error = "新增保通知出错，数据库应该返回1,但返回了 "+rows;
			throw new BusinessException(error);
		}
		return notice;
	}

	/**
	 * 更新维修评价
	 *
	 * @param notice 实体对象
	 */
	@Override
	public Notice updateNotice(Notice notice){
		//TODO:请在此校验参数的合法性
		this.validateUpdateNotice(notice);
		Long rows = this.noticeDao.updateNotice(notice);
		if(rows != 1)
		{
			String error = "修改保通知出错，数据库应该返回1,但返回了 "+rows+",数据可能被删除";
			throw new BusinessException(error);
		}
		return notice;
	}

	/**
	 * 根据ID删除维修评价
	 *
	 * @param noticeId ID
	 */
	@Override
	public void deleteNotice(Long noticeId){
		//TODO:请在此校验参数的合法性
		this.validateDeleteNotice(noticeId);

		Map<Class<? extends BaseEntity>,EntityUsage> entityUsageMap = this.checkForeignEntity(Notice.class, noticeId);
		if(entityUsageMap != null && entityUsageMap.size() >0){
			StringBuilder errors = new StringBuilder();
			errors.append("计划删除的数据正在被以下数引用\n");
			for(EntityUsage entityUsage : entityUsageMap.values()){
				errors.append("\t").append(entityUsage.getEntityLabel()).append("\n");
				for(Map.Entry<Long,String> entry : entityUsage.getUsageIdNames().entrySet() ){
					errors.append("\t\t").append(entry.getKey()).append("\t").append(entry.getValue()).append("\n");
				}
			}
			errors.append("，不能删除，请检查处理后再删除");
			throw  new BusinessException(errors.toString());
		}

		Long rows = this.noticeDao.deleteNotice(noticeId);
		if(rows != 1){
			String error = "删除维修评价出错，数据可能已经被删除";
			throw new BusinessException(error);
		}
	}

	@Override
	public JsonResult pushNotice(Long noticeId) {
		this.noticeDao.pushNotice(noticeId);
		Notice notice = this.noticeDao.findNotice(noticeId);
		//生成应的NoticeCatUser  generate
		JsonResult generate = this.noticeCatUserService.generate(noticeId, notice.getNoticeType(), notice.getSelectedString());
		return generate;
	}

	@Override
	public JsonResult findNotReadNoticeUser(Long noticeId) {
		List<User> userList=this.noticeCatUserDao.findNotReadNoticeUser(noticeId);
		return JsonResult.ok("查询成功").put("notReadNoticeUserList",userList);
	}

	@Override
	public JsonResult findReadNoticeUser(Long noticeId) {
		List<User> userList=this.noticeCatUserDao.findReadNoticeUser(noticeId);
		return JsonResult.ok("查询成功").put("readNoticeUserList",userList);
	}

	//TODO:---------------验证-------------------

	private void validateFindNotices(PageDTO pageDTO) {
	//TODO:请使用下面方法添加数据过滤条件
	//		pageDTO.addFilter("creatorId",this.getLoginUserId());
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateNotice()写法
	}

	private void validateFindNoticesWithIdNameByName(String noticeName) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateNotice()写法
	}


	private void validateFindAllNoticesWithIdName() {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateNotice()写法
	}

	private void validateFindNoticesWithIdNameById(Long noticeId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateNotice()写法
	}

	private void validateFindNotice(Long noticeId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateNotice()写法
	}

	private void validateFindNoticeWithForeignName(Long noticeId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateNotice()写法
	}

	private void validateSaveNotice(Notice notice) {
	//不为空判断
	if (notice.getEid() != null || notice.getCreatorId() != null || notice.getCreateDatetime() != null) {
	throw new BusinessException("非法请求");
	}
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateNotice()写法
	}

	private void validateUpdateNotice(Notice notice) {
	//不为空判断
	if (notice.getEid() == null) {
	throw new BusinessException("唯一标识不能为空");
	}
	//是否存在判断
	if (this.noticeDao.findNoticeTotalCount(PageDTO.create(Notice.FIELD_ID, notice.getEid())) == 0) {
	throw new BusinessException("修改的维修评价 " + notice.getName() + " 不存在，修改失败，请重试或联系管理员");
	}
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateNotice()写法
	}

	private void validateDeleteNotice(Long noticeId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateNotice()写法
	}

	@Override
	public boolean canDownloadAttachment(String formName, Long id) {
	return true;
	}
}
